package com.lzy.chat.f_config;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.lzy.chat.a_entity.User;
import com.lzy.chat.b_mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;

import java.util.Map;

public class HandshakeInterceptor extends HttpSessionHandshakeInterceptor {

    private UserMapper userMapper;

    @Autowired
    public void setUserMapper(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) {
        HttpHeaders headers = request.getHeaders();
        String token = headers.getFirst("token");
        if (token == null) {
            response.setStatusCode(HttpStatus.FORBIDDEN);
            return false;
        }
        String userId;
        try {
            userId = JWT.decode(token).getAudience().get(0);
        } catch (JWTDecodeException j) {
            response.setStatusCode(HttpStatus.FORBIDDEN);
            return false;
        }
        User user = userMapper.getUserById(Integer.parseInt(userId));
        if (user == null) {
            response.setStatusCode(HttpStatus.FORBIDDEN);
            return false;
        }
        JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getSalt())).build();
        try {
            jwtVerifier.verify(token);
        } catch (JWTVerificationException e) {
            response.setStatusCode(HttpStatus.FORBIDDEN);
            return false;
        }
        //attributes中放入id,以便在websocketController中可以通过session获取到这些数据
        attributes.put("id", user.getId());//放入id
        attributes.put("token", token);//放入token
        return true;
    }
}
